/*
 * vibration.c
 *
 *  Created on: 2017年5月4日
 *      Author: chenss
 */

#include "io/vibration.h"
#include "io.h"
#include "ctimer.h"
#include "message_queue.h"

static bool _isEnabled;
//static BitAction _pinStatus;
static int _vibrateCounter, _quietCounter;
static int _freq;
static Ctimer_t _timer;
//static int _sensitivity;

static void _ExtiInit(void);

void Vibration_Init(void)
{
    _isEnabled = TRUE;
    _freq = 0;

//    IO_Request(IO_Vibration);
    _ExtiInit();
//    _pinStatus = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);

//    _sensitivity = 5;
}

static void _ExtiInit(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Enable GPIOC clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    /* Enable SYSCFG clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Configure pins as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);

    EXTI_InitStructure.EXTI_Line = EXTI_Line12;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Enable and set EXTI4_15 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

static void _OnTimeout(void)
{
    _freq = _vibrateCounter;
    _vibrateCounter = 0;

    if(_freq != 0)
    {
        MsgQueue_Send(MsgQueue_Id_Vibration, & _freq, sizeof(_freq));
    }
    else
    {
        _quietCounter += 1;
        if(_quietCounter >= 5)
        {
            Ctimer_Stop(& _timer);

            MsgQueue_Send(MsgQueue_Id_Vibration, & _freq, sizeof(_freq));
        }
    }
}

void Vibration_EXTI12Handler(void)
{
//    BitAction status;

    if(EXTI_GetITStatus(EXTI_Line12) == RESET)
    {
        return;
    }
    EXTI_ClearITPendingBit(EXTI_Line12);

    if(! _isEnabled)
    {
        return;
    }

//    status = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);
//    if(status == _pinStatus)
//    {
//        return;
//    }

    if(! Ctimer_IsRunning(& _timer))
    {
        _vibrateCounter = 0;
        _quietCounter = 0;
        Ctimer_Start(& _timer, 1000, _OnTimeout, 0);
    }

    _vibrateCounter += 1;
//    _pinStatus = status;

}

void Vibration_Set(int isEnable)
{
    EXTI_InitTypeDef EXTI_InitStructure;

//    _sensitivity = isEnable;
    if(! isEnable)
    {
        _isEnabled = FALSE;
        if(Ctimer_IsRunning(& _timer))
        {
            Ctimer_Stop(& _timer);
        }

        EXTI_InitStructure.EXTI_Line = EXTI_Line12;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        EXTI_InitStructure.EXTI_LineCmd = DISABLE;
        EXTI_Init(&EXTI_InitStructure);
    }
    else
    {
        _isEnabled = TRUE;
        EXTI_InitStructure.EXTI_Line = EXTI_Line12;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
    }

    debug("Vibration: %s\r\n", isEnable ? "On" : "Off");
}

void Vibration_Pause(bool isPause)
{
    EXTI_InitTypeDef EXTI_InitStructure;

    if(! _isEnabled)
    {
        return;
    }

    if(isPause)
    {
//        _isEnabled = FALSE;
//        if(Ctimer_IsRunning(& _timer))
//        {
//            Ctimer_Stop(& _timer);
//        }

        EXTI_InitStructure.EXTI_Line = EXTI_Line12;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        EXTI_InitStructure.EXTI_LineCmd = DISABLE;
        EXTI_Init(&EXTI_InitStructure);
    }
    else
    {
//        _isEnabled = TRUE;
        EXTI_InitStructure.EXTI_Line = EXTI_Line12;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
    }
}

int Vibration_Get(void)
{
    return _isEnabled;
}

int Vibration_GetFreq(void)
{
    return _freq;
}
